// License Notification
//======================================================
// Copyright (c) 2010 Channel Intelligence Inc.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// ======================================================




using System;
using System.Collections.Generic;
using Plossum.CommandLine;
using CIP4.Common;
using CIP4.Simple;

namespace CIP4.Installer
{
    [CommandLineManager(
        ApplicationName = InstallerProgram.Appname,
        Description = "A commandline app",
        Copyright = "Copyright 2010 Channel Intelligence Inc")]
    class OptionsType
    {
        // plossum uses reflection to get to these variables, which the compiler can't see, so supppress never assigned warnings
#pragma warning disable 0649

        [CommandLineOption(Description = "help text",
            Aliases = "?", Prohibits = "Confirm")]
        public bool Help;

        [CommandLineOption(Description = 
            "Action to perform, \n" + 
            "none - do nothing\n" + 
            "list - list the currently installed connections and the available types of connection\n" +
            "add - add or install a new connection - you must provide a target which indicates the type of connection you want to add or install\n" +
            "delete - deletes the given configuration\n",
            Aliases = "a")]
        public ActionEnum Action { get; set; }

        public enum ActionEnum
        {
            None,
            List,
            Add,
            Delete
        }

        [CommandLineOption(Description = "The type of provider to install or add a connection for. Use /a list to see the currently available types of connection",
            Aliases = "t")]
        public ProviderTypesEnum Target { get; set; }

        [CommandLineOption(Description = "The name to use to identify the connection - if you don't supply one, one will be built from the connection properties",
            Aliases = "n")]
        public string Name { get; set; }

        [CommandLineOption(Description = "The accountto use when using /action Add with Cassandra or MongoDB - something like channelinc\\fred.smith",
            Aliases = "acc")]
        public string Account { get; set; }

        [CommandLineOption(Description = "The password to use when using /action Add with Cassandra or MongoDB",
            Aliases = "pwd")]
        public string Password { get; set; }

        [CommandLineOption(Description = "Displays sensitive data such as passwords and secret keys",
            Aliases = "ssd")]
        public bool ShowSensitiveData { get; set; }

        [CommandLineOption(Description = "Displays the current options and asks for confirmation before continuing",
            Aliases = "c")]
        public bool Confirm { get; set; }

        [CommandLineOption(Description = "Controls how much gets written to the log, Error, Warning, Information - Information being the most verbose", Aliases = "l")]
        public MajorEnum LoggingLevel { get; set; }

        public Dictionary<string, List<string>> ParameterValues = new Dictionary<string, List<string>>(StringComparer.CurrentCultureIgnoreCase);

        [CommandLineOption(Description = "The parameters to be passed to the job. Each parameters value must be in the form <name>:<value>. Where <name> is the name of a parameter and <value> is the value to be associated with the name. You can provide the same name multiple times with different values. Use /a list to see the parameters required by the different connection types. If a parameter is required and you don't provide it, you will be asked for it",
            Aliases = "p", MaxOccurs = 100)]
        public void Parameters(string value)
        {
            ParseKvp(value, ParameterValues);
        }

#pragma warning restore 0649

        private static void ParseKvp(string value, IDictionary<string, List<string>> values)
        {
            if (value.IndexOf(':') == -1)
                throw new ArgumentException(string.Format("The parameter value {0} is not valid - it must consist of a name seperated from a avalue by a colon character", value));
            string key = value.Substring(0, value.IndexOf(':')).ToLower();
            string v = value.Substring(key.Length + 1);
            if (string.IsNullOrEmpty(v))
                throw new ArgumentException(string.Format("The parameter value {0} is not valid - it must consist of a name seperated from a non-empty value by a colon character", value));
            if (values.ContainsKey(key))
                values[key].Add(v);
            else
                values.Add(key, new List<string> { v });
        }

        public override string ToString()
        {
            string text = string.Format("/Action {0} /LoggingLevel {1}", Action, LoggingLevel);
            foreach (KeyValuePair<string, List<string>> kvp in ParameterValues)
                foreach (string value in kvp.Value)
                    text += string.Format(" /{0} \"{1}\"", kvp.Key, value);
            return text;
        }
    }
}
